package com.xms.sdk.api.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xms.core.data.Entity;
import com.xms.schema.entity.Attribute;
import com.xms.schema.entity.RelationShip;
import com.xms.schema.service.attribute.IAttributeFinderService;
import com.xms.schema.service.entity.IEntityFinderService;
import com.xms.schema.service.relationship.IRelationShipFinderService;
import com.xms.sdk.api.model.SaveChildDataModel;
import com.xms.sdk.core.EntityReference;
import com.xms.sdk.extensions.EntityWrapper;
import com.xms.sdk.service.IDataCreater;
import com.xms.sdk.service.IDataUpdater;
import com.xms.utils.CollectionUtil;
import com.xms.utils.StringUtil;
import com.xms.utils.UUIDUtil;
import com.xms.web.framework.controller.ApiBaseController;
import com.xms.web.framework.model.JsonResultObject;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * DataSaveController
 * </p>
 *
 * @author migo
 * @since 2021/9/16
 */
@RestController
@RequestMapping("{org}/api/data")
public class DataSaveController extends ApiBaseController {
    private IEntityFinderService _entityFinderService;
    private IAttributeFinderService _attributeFinderService;
    private IRelationShipFinderService _relationShipFinderService;
    private IDataCreater _dataCreater;
    private IDataUpdater _dataUpdater;
    @Autowired
    public DataSaveController(IEntityFinderService entityFinderService
            , IAttributeFinderService attributeFinderService
            , IRelationShipFinderService relationShipFinderService
            , IDataCreater dataCreater
            , IDataUpdater dataUpdater)
    {
        _entityFinderService = entityFinderService;
        _attributeFinderService = attributeFinderService;
        _relationShipFinderService = relationShipFinderService;
        _dataCreater = dataCreater;
        _dataUpdater = dataUpdater;
    }

    @ApiOperation("保存单据体数据")
    @PostMapping("savechilds")
    public JsonResultObject savechilds(SaveChildDataModel model) throws Exception {
        if (StringUtil.isEmpty(model.Child))
        {
            return JError("data is empty");
        }
        JSONArray childs = JSONArray.parseArray(StringUtil.urlDecode(model.Child));
        if (childs.size() > 0)
        {
            com.xms.schema.entity.Entity entityMeta = _entityFinderService.getByName(model.EntityName);
            if (entityMeta == null)
            {
                return JNotFound();
            }
            UUID entityid = entityMeta.getEntityid();
            List<Entity> childEntities = new ArrayList<>();
            List<String> entityNames = new ArrayList<>();
            Iterator childIter = childs.iterator();
            while(childIter.hasNext())
            {
                JSONObject root = (JSONObject)childIter.next();
                String name = root.getString("name"), relationshipname = root.getString("relationshipname"), refname = "";
                if (!entityNames.contains(name))
                {
                    entityNames.add(name);
                }

                List<Attribute> childAttributes = _attributeFinderService.getByEntityName(name);
                if (StringUtil.notEmpty(relationshipname))
                {
                    RelationShip relationShipMetas = _relationShipFinderService.getByName(relationshipname);
                    if (null != relationShipMetas
                            && relationShipMetas.getReferencedentityid().equals(entityid))
                    {
                        refname = relationShipMetas.getReferencingattributename();
                    }
                }
                JSONObject data = root.getJSONObject("data");
                Entity detail = new Entity(name);
                Iterator childItemIter = data.entrySet().iterator();
                while(childItemIter.hasNext()) {
                    Map.Entry entry = (Map.Entry) childItemIter.next();
                    String key = entry.getKey().toString().toLowerCase();
                    Object value = entry.getValue();
                    Attribute attr = childAttributes.stream().filter(n -> n.getName().equalsIgnoreCase(key)).findFirst().orElse(null);
                    if (attr != null && value != null) {
                        detail.setValue(key, EntityWrapper.wrapAttributeValue(detail, _entityFinderService, attr, value.toString()));
                    }
                }
                //关联主记录ID
                if (StringUtil.notEmpty(refname))
                {
                    detail.setValue(refname, new EntityReference(entityMeta.getName(), model.ParentId));
                }
                childEntities.add(detail);
            }
            //批量创建记录
            if (CollectionUtil.notEmpty(childEntities))
            {
                for (String item : entityNames)
                {
                    int creatingCount = 0;
                    List<com.xms.core.data.Entity> items = childEntities.stream().filter(n -> n.Name.equalsIgnoreCase(item)).collect(Collectors.toList());
                    List<com.xms.core.data.Entity> creatingRecords = items.stream().filter(n -> n.Name.equalsIgnoreCase(item) && UUIDUtil.isEmpty(n.getIdValue())).collect(Collectors.toList());
                    if (CollectionUtil.notEmpty(creatingRecords))
                    {
                        _dataCreater.createMany(creatingRecords);
                        creatingCount = creatingRecords.size();
                    }
                    if (creatingCount < childEntities.size())
                    {
                        List<com.xms.core.data.Entity> updatingRecords = items.stream().filter(n -> n.Name.equalsIgnoreCase(item) && UUIDUtil.notEmpty(n.getIdValue())).collect(Collectors.toList());
                        for (com.xms.core.data.Entity updItem : updatingRecords)
                        {
                            _dataUpdater.update(updItem);
                        }
                    }
                }
            }
        }
        return JSaveSuccess();
    }
}
